查看原文
其他

《爱上潘大师》系列-必须学会的数据清洗操作

小一 小一的学习笔记 2023-01-01

2020,努力做一个无可替代的人!


作者 | 小一

全文共3667字,阅读全文需12分钟



写在前面的话

不知道你看了本系列上节文末小一的碎碎念有没有心里默默为自己定下一个小目标

我们对于未知的事物会充满好奇心,对于设定的目标也会有完成的决心。

如果你也能坚持下来,那你必会成为成功队列中一员。

复习一下前面的文章:

今天会介绍一些数据分析的常用方法,你准备好了吗?


正文

学数据分析的人都说Pandas 功能强大,可以快速进行数据预处理。但是肯定不是因为上一节,基础嘛,大家都明白。

利用Excel 做表格的时候,最常用的方法就是筛选、过滤、转换和数据匹配

那么Pandas 就是帮助我们快速实现这些功能的一种方法

这一节主要就讲些数据处理常用的方法:

  • 数据的多种选取方式

  • 异常、缺失值的处理

  • 数据过滤、删除


数据的选取

我们知道,对于只有行索引的数据,可以通过下标或行索引进行选择

那对于DataFrame 类型的数据,在原有行索引选择的基础上新增了列索引选择

DataFrame 中数据的选取有挺多种方法的,比如:loc、iloc、at、iat等

希望你看完本节内容能够有一个清楚的认识


首先先创建一个有行、列索引的数据集

# 创建一个带行、列索引的数据集
dict_data = {
                'name': ['zhangsan''lisi''wangwu''zhaoliu'],
                'age': [111417None],
                'score': [95.594.597None]
            }
index = ['one''two''three''four']
df_data = pd.DataFrame(dict_data, index=index)

# 输出
           name   age  score
one    zhangsan  11.0   95.5
two        lisi  14.0   94.5
three    wangwu  17.0   97.0
four    zhaoliu   NaN    NaN


通过loc 选取数据
loc 函数是基于“标签”选取数据的,也可以接受一个boolean 类型的array

既然是基于标签,那肯定可以通过行索引选取单行数据

# 通过loc 行标签/索引选取单行数据
df_data.loc['two']

单行是可以的,那多行也没问题

通过 [标签名1, 标签名2, 标签名3] 选取多行数据

# 通过loc 行标签/索引选取多行数据
df_data.loc[['two''three''four']]
多行数据的选取可以通过切片方式选取吗?

真是个小机灵鬼,当然可以用切片,而且比多标签的方式更简便

# 通过loc 切片选取多行数据
df_data.loc['two':'four']


当然,你也可以传入一个boolean 类型的array

# 通过loc boolean 数组选取数据
df_data.loc[[FalseTrueFalseTrue]]

以上的都是基于行的数据选取,如果要在此基础上新增列的选择呢?

保持行的选取方式不动,直接在loc 中新增列选取

例如:在2-4行的数据中,选取name 和age 列

# 通过loc 行、列标签共同选取
df_data.loc['two':'four', ['name''age']]

行数据选取可以选多行、可以用切片方式、可以用Boolean 数组

列数据选取同样适用


如何想对数据进行判断,只输出自己想要的数据呢,怎么选取?

这个就需要灵活运用了,我举个例子,你可参考一下

# 通过loc 筛选输出想要的结果
df_data.loc[df_data1['age']>15, ['name''age']]


通过iloc 选取数据

不同于loc 选取数据,iloc 接收的是一个数字,即通过下标选取数据

相同的是,iloc 也可以选取单行与多行数据,而且也可通过切片、boolean数组选取多行数据

# 通过 iloc 下标选取单行数据
df_data.iloc[1]
# 通过 iloc 下标选取多行数据
df_data.iloc[[123]]
# 通过 iloc 切片方式选取多行数据
df_data.iloc[1:4]
# 通过iloc boolean数组选取数据
df_data.iloc[[FalseTrueFalseTrue]]
上面的都是行的选取,那列呢?

同样的,我们通过下标选取行数据,也可以通过下标选取列数据

# 通过 iloc 下标选取行、列数据
df_data.iloc[1:41]
df_data.iloc[1:4, [12]]
df_data.iloc[1:40:2]

loc 方式和iloc 方式选取数据应该清楚了吧:loc 是通过标签,iloc 是通过下标

下面还有一堆孪生兄弟,继续往下看

通过at 选取数据

at 和loc 最大的区别是:at 是选择单个值的,loc 可以选择数据块

其他的用法和 loc 都相同,都是通过标签选取数据

# 通过at 选取数据
df_data.at['one''name']

选取数据必须行、列标签都设置,否则会报错

通过iat 选取数据

同at 的选取方式,只可选取单个值

不同的是,iat 是通过下标选取数据

# 通过iat 选取行数据
df_data.iat[10]


就这四种方式,大家不要搞混了,稍微总结一下:

  • loc:通过标签选取数据,可以选取数据块

  • at:通过标签选取数据,只能选取数据值

  • iloc:通过下标选取数据,可以选取数据块

  • iat:通过下标选取数据,只能选取数据块

也就是下面这张表,看的会更清楚些:


通过标签选取数据通过下标选取数据
选取数据块lociloc
选取数据值atiat

还有通过ix 方式选取数据,官方已经弃用了,在这就不介绍了。

缺失值的处理

缺失数据在数据分析中是最常见的,Pandas 中使用 NaN(Not a Number) 表示浮点和非浮点数组中的缺失数据。

Python 中内置的None 值也会被当做 NaN处理

DataFrame 中缺失数据有四种处理方法

方法说明
dropna根据各标签的值中是否存在缺失数据对轴标签进行过滤
fillna用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull返回一个含有布尔值的对象,表示哪些值是缺失值
notnullisnull 的否定形式

在我们文章一开始创建的 DataFrame 中,就存在缺失值

df_data

# 输出
           name   age  score
one    zhangsan  11.0   95.5
two        lisi  14.0   94.5
three    wangwu  17.0   97.0
four    zhaoliu   NaN    NaN

只不过,这个缺失值是在创建的时候手动设置的。


要处理缺失值之前,如何检测缺失值呢?

通过isnull 方法可以迅速检测出缺失值

# 检测缺失值
df_data.isnull()

# 输出
        name    age  score
one    False  False  False
two    False  False  False
three  False  False  False
four   False   True   True

缺失的数据会输出 True,你也可以只输出缺失的数据行或者列

另外,也可以额通过 isnull 的否定形式 notnull 检测缺失值


如何过滤缺失数据呢?

使用 dropna 方法可以过滤缺失数据,需要注意的是dropna  的两个参数。分别是 how 和 axis

  • how:如果该行或列数据存在/全部为空值,则删除。any表示存在为空,all表示全部为空。默认为 any

  • axis:表示丢弃行、列。默认为 0轴

例如上面的数据集,我们需要删除空值行

# 删除存在空值的行
df_data = df_data.dropna(axis=0, how='any')
# 或者设置inplace 参数达到同样的效果
df_data.dropna(axis=0, how='any', inplace=True)

或者需要删除全部为空值的列

# 删除全部为空值的列
df_data.dropna(axis=1, how='all', inplace=True)


那如何填充缺失数据呢?

填充缺失值,有很多种填充方法

你可以使用该指标的平均数、中位数,或者通过算法模拟出这个指标的分布,填充一个合适的值,都可以

最常见的方法就是通过平均值填充(比较不靠谱,只是做个示范)

例如,在age 列,需要填充zhaoliu 的年龄

# 计算age 列的平均值
avg_age = df_data1['age'].mean()
# 利用平均值填充缺失值
df_data['age'].fillna(avg_age, inplace=True)

# 输出
           name   age  score
one    zhangsan  11.0   95.5
two        lisi  14.0   94.5
three    wangwu  17.0   97.0
four    zhaoliu  14.0    NaN


同样的,需要填充 zhaoliu 的 得分情况,这里我们可以用最小值填充

# 计算score 列的最小值
min_score = df_data['score'].min()
# 利用最小值填充缺失值
df_data['score'].fillna(min_score, inplace=True)

# 输出
           name   age  score
one    zhangsan  11.0   95.5
two        lisi  14.0   94.5
three    wangwu  17.0   97.0
four    zhaoliu  14.0   94.5

缺失值的填充很大程序上决定了分析结果的准确程度

所以在缺失值填充的过程中,尽量的先了解指标的具体含义,了解具体业务情况,然后再选择合适的方法进行填充


数据过滤

前面说到通过四种方式选取数据,没忘记吧?

我们可以在过滤数据的时候这样用:

# 筛选年龄大于11的数据
df_data[df_data.age>11]

当有多个筛选条件,需要用到 & 运算符,且筛选条件必须用 () 括住

例如:年龄大于11且成绩大于95的所有数据

# 多条件筛选
df_data[(df_data.age>11) & (df_data.score>95)]


多条件共同筛选是用 &实现“与”的功能,那“或”的功能用什么?

这个需要注意,DataFrame中的与或非分别用 & | ~表示

例如:年龄小于15或者成绩大于95的所有数据

# 多条件或运算
df_data[(df_data.age<11) | (df_data.score>95)]

再例如:除了张三以为的所有人的数据

# 非运算的实现
df_data[~(df_data.name=='zhangsan')]


我们在取多列数据也可以这样取:

# 选取多列数据
df_data[['name''age']]


合并起来,筛选出我们想要的数据,再输出我们想要的列

例如:筛选年龄大于11的数据,且只输出name、age列

# 先筛选,再输出指定列
df_data[df_data.age>11][['name''age']]
# 先输出指定列,再筛选
df_data[['name''age']][df_data.age>11]

上面两种方法都可以达到相同的效果,根据自己的习惯选择

数据删除

删除数据会经常用到 drop 方法,这个一定要掌握

例如:删除单行数据和删除多行数据

# 删除单行数据
df_data = df_data.drop('one')
# 删除多行数据
df_data = df_data.drop(['two''three'])


如果删除列数据呢?怎么操作

更改参数 axis 的值即可,axis默认为0,表示行操作,改为1则表示列操作

# 删除列数据
df_data = df_data.drop(['age''score'], axis=1)

另外,drop 方法有一个参数 inplace,表示是否真正删除,默认为False

df_data.drop('name', axis=1, inplace=True)

是不是很简单?

就一个函数,掌握了就可以随便对数据进行花式删除操作


总结一下:

今天主要介绍了数据分析的一些常用方法,比较详细。

但是可能会缺少一些实际的项目让大家加深理解,没关系,这系列完结了会开始分享项目实战的。

再来回顾一下这节内容,这一节主要就讲些数据处理常用的方法:

  • 数据的多种选取方式

  • 异常、缺失值的处理

  • 数据过滤、删除

可能会有遗漏,但是相信最常用、最高效的都在里面了。

以后若有更新,我会新出完整的一期,带上项目实战一起。

记得置顶公众号,持续关注就好!


写在后面的话

最近要学的东西有点多,少有时间写文章。

Pandas 系列还是会按期写完的,这个大家放心

碎碎念一下

最近在交流群里开了一个每日一题的活动

题目基本上都是一些基本的Python 语法题,你可以用简单语法,也可以用高阶函数去实现。

这些题有些会是面试题,掌握相关解题技巧还是很有必要的。


需要加群同学的在后台回复“加群”


下节见!





好巧啊,你也读到这了!    

点个在看让我看到你

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存